package com.ybkj.daijia.api.aliyun.certification;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.cloudauth.model.v20190307.CompareFacesRequest;
import com.aliyuncs.cloudauth.model.v20190307.CompareFacesResponse;
import com.aliyuncs.cloudauth.model.v20190307.CompareFacesResponse.Data;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.ybkj.daijia.api.Constant;
import com.ybkj.daijia.api.RealPeopleCertificationApi;
import com.ybkj.daijia.api.aliyun.AliyunApi;
import com.ybkj.daijia.api.thirdpardCommon.ThirdPartResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * @author zhyu
 * @date 2019/12/27 11:10 阿里云 实人认证api, 调的是其人脸比对接口 https://help.aliyun.com/document_detail/59317.html 参数文档 https://help.aliyun.com/document_detail/127684.html?spm=a2c4g.11186623.6.623.39e6530d22YOry
 * 要求body在8M以内, 单张图片要求2M以内
 * 收费方式免费的用完后调就是6厘钱, 要便宜点可以买流量包。
 */
@Component
@Slf4j
public class AliyunRealPeopleCertificationApi implements RealPeopleCertificationApi, AliyunApi {

    /**
     * 阿里云推荐的几率阈值
     */
    public static final String recommendProbability = "0.001";
    /***
     * 表示上传的图像是人脸像, 其中表示身份证图像的应该用字段   private static final String ID_PIC = "IDPic";
     */
    private static final String FACE_ID = "FacePic";

    @Override
    public ThirdPartResult<RealPeopleCertificationResult> compareTwoHeadPhotoes(String urlA, String urlB, String base64A, String base64B) {
        DefaultProfile profile = DefaultProfile.getProfile(
            //默认
            getRegionId(),
            //您的Access Key ID
            getAccessKeyId(),
            //您的Access Key Secret
            getAccessSecret());
        IAcsClient client = new DefaultAcsClient(profile);
        //创建API请求并设置参数
        //CompareFaces接口文档：
        CompareFacesRequest request = new CompareFacesRequest();
        request.setMethod(MethodType.POST);
        //传入图片资料，请控制单张图片大小在 2M 内，避免拉取超时
        boolean aIsOK = null != urlA || null != base64A;
        boolean bIsOK = null != urlB || null != base64B;
        ThirdPartResult<RealPeopleCertificationResult> result = new ThirdPartResult<>();
        if (aIsOK && bIsOK) {
            //base64方式上传图片, 格式为"base64://图片base64字符串", 以"base64://"开头且图片base64字符串去掉头部描述(如"data:image/png;base64,"), 并注意控制接口请求的Body在8M以内
            //若为身份证芯片照则传"IDPic"
            //http方式上传图片, 此http地址须可公网访问
            request.setSourceImageType(FACE_ID);
            if (null != urlA) {
                request.setSourceImageValue(urlA);
            } else {
                request.setSourceImageValue(Constant.BASE64_PROTOCOL + base64A);
            }
            request.setTargetImageType(FACE_ID);
            if (null != urlB) {
                request.setTargetImageValue(urlB);
            } else {
                request.setTargetImageValue(Constant.BASE64_PROTOCOL + base64B);
            }
            try {
                long start = System.currentTimeMillis();
                CompareFacesResponse response = client.getAcsResponse(request);
                long end = System.currentTimeMillis();
                if (log.isInfoEnabled()) {
                    log.info("aliyun api cost {} seconds. requestId {}", (end - start) / 1000, response.getRequestId());
                }
                result.setStatusCode(response.getCode());
                result.setSuccess(response.getSuccess());
                result.setMessage(response.getMessage());
                if (result.getSuccess()) {
                    Data data1 = response.getData();
                    if (null != data1) {
                        RealPeopleCertificationResult data = new RealPeopleCertificationResult();
                        result.setData(data);
                        data.setSimilarityScore(data1.getSimilarityScore());

                        JSONObject jsonObject = JSON.parseObject(response.getData().getConfidenceThresholds());
                        data.setConfidenceThresholds(jsonObject);
                        //分析相识度和阈值, 提供建议给外层
                        Double aDouble = jsonObject.getDouble(recommendProbability);
                        if (aDouble != null) {
                            if (data.getSimilarityScore() > aDouble) {
                                data.setRecommendResult(true);
                            }
                        }
                    }
                }
            } catch (ServerException e) {
                if (log.isErrorEnabled()) {
                    log.error("服务器错误", e);
                }
            } catch (ClientException e) {
                if (log.isErrorEnabled()) {
                    log.error("客服端错误", e);
                }
            }
        }
        return result;
    }
}

